import {defineAsyncComponent} from "vue";
import progress from "nprogress";
import 'nprogress/nprogress.css'
import {fetchMenusByUser, signToken} from "@/store";
import {getHistory, setHistory} from "@/utils/storage";

const whiteList = ['/login']//白名单
let isInjectRoutes = false //是否鉴权标志

//解析路径所对应的视图组件位置
const _resolveComponentUrl = ({children, path}, level) => {
  if (!children || children.length === 0) return "views" + path
  if (level === 0) return 'layout/index'
  return 'layout/EmptyLayout'
}

const _resolveIconNode = (icon) =>
    defineAsyncComponent(() => import('@element-plus/icons-vue/dist/es/' + icon.toLowerCase()))

//权限树装载视图组件
const _loadComponent = (perms, level = 0) => {
  return perms.map(item => {
    const url = _resolveComponentUrl(item, level)
    item.component = () => import("@/" + url)
    const icon = item.icon?.trim() ?? item?.meta?.icon
    if (icon) {
      item.meta.iconNode = _resolveIconNode(icon)
    }
    if (item.children && item.children.length>0) {
      item.children = _loadComponent(item.children, level+1)
      item.redirect = item.children[0].path
    } else {
      delete item.children
    }
    if(item.name){
      item.name = item.name.trim()
    }
    return item
  })
}

//鉴权生成权限权限路由
const generateRoutes = async (tree) => {
  const authRoutes = _loadComponent(tree)
  authRoutes.unshift({path: '/', redirect: authRoutes[0].path})
  return Promise.resolve(authRoutes)
}

function registryPermission(router) {
  router.beforeEach(async (to) => {
    progress.start()
    const toPath = to.path
    if (whiteList.includes(toPath)) {  //权限白名单，直接通过
      return true
    }
    if (signToken.value) {
      if (toPath !== '/' && toPath !== '/login') {
        setHistory({path: toPath, query: to.query})    //记录用户上次访问的位置
      }
      if (isInjectRoutes) {
        return true
      }
      const userMenus = await fetchMenusByUser()
      // console.log(userMenus,"路由树");
      const authRoutes = await generateRoutes(userMenus)
      // console.log(authRoutes, "authRoutes")
      for (const route of authRoutes) {
        router.addRoute(route)
      }
      // console.log(router.getRoutes())
      isInjectRoutes = true
      const historyTo = getHistory();
      if (historyTo)
        return {...historyTo, replace: true}
      return {path: toPath, query: to.query, replace: true}
    }
    return '/login'
  })
  router.afterEach((to,from) => {
    progress.done()
    // console.log(to);
    window.parent.postMessage({name: to.name,url: to.fullPath, title: to.meta.title}, '*')
  })
}

export default registryPermission
